#include "EDBaseAfx.h"
#include "GPIniFile.h"

#define MAX_INIFILE_BUFFER_SIZE 2048


GPIniFile::GPIniFile(std::wstring FileName)
{
	m_strFileName = FileName;
}

GPIniFile::GPIniFile(LPCWSTR FileName)
{
	m_strFileName = FileName;
}

GPIniFile::~GPIniFile()
{
}

bool GPIniFile::SectionExists(std::wstring Section)
{
	inistringlist Strings;
	ReadSection(Section, Strings);
	return Strings.size()>0;
}

std::wstring GPIniFile::ReadString(std::wstring Section, std::wstring Ident, std::wstring Default)
{

	int nSize = 0, nLen = nSize-2;
	wchar_t *lpszReturnBuffer = 0;
	while(nLen==nSize-2)
	{
		nSize+=MAX_INIFILE_BUFFER_SIZE;
		if(lpszReturnBuffer) 
			delete [] lpszReturnBuffer;
		lpszReturnBuffer = new wchar_t[nSize];
		nLen = GetPrivateProfileStringW(Section.c_str(),
			Ident.c_str(),
			Default.c_str(),
			lpszReturnBuffer,//
			nSize,
			m_strFileName.c_str());	//
	}
	std::wstring Ret;
	if(lpszReturnBuffer)
	{
		Ret = lpszReturnBuffer;
		delete[] lpszReturnBuffer;
	}
	return Ret;
}

bool GPIniFile::WriteString(std::wstring Section, std::wstring Ident, std::wstring Value)
{
	if(WritePrivateProfileStringW(Section.c_str(),
		Ident.c_str(),
		Value.c_str(),
		m_strFileName.c_str())==0)
		return false;
	else
		return true;
}

int GPIniFile::ReadInt32(std::wstring Section, std::wstring Ident, int Default)
{
	std::wstring strInt = ReadString(Section,Ident,L"");
	if (strInt.size() <= 0)
	{
		return Default;
	}
	else
	{
		return _wtoi(strInt.c_str());
	}
}

bool GPIniFile::WriteInt32(std::wstring Section, std::wstring Ident, int Value)
{
	wchar_t buffer[20];
	_itow_s(Value,buffer,10);
	return WriteString(Section.c_str(),Ident.c_str(),buffer);
}

LONGLONG GPIniFile::ReadInt64(std::wstring Section, std::wstring Ident, LONGLONG Default)
{
	std::wstring strInt = ReadString(Section,Ident,L"");
	if (strInt.size() <= 0)
	{
		return Default;
	}
	else
	{
		return _wtoi64(strInt.c_str());
	}
}

bool GPIniFile::WriteInt64(std::wstring Section, std::wstring Ident, LONGLONG Value)
{
	TCHAR buffer[MAX_PATH];
	ZeroMemory(buffer, sizeof(TCHAR) * MAX_PATH);
	_i64tow_s(Value, buffer,_countof(buffer)-1, 10);
	return WriteString(Section.c_str(),Ident.c_str(),buffer);
}

int GPIniFile::ReadIntegerHex(std::wstring Section, std::wstring Ident, int Default)
{
	std::wstring strInt = ReadString(Section,Ident,L"");
	if (strInt.size() <= 0)
	{
		return Default;
	}
	else
	{
		int   ret = Default;
		swscanf_s(strInt.c_str(),L"%x", &ret);		
		return ret;
	}
}

bool GPIniFile::WriteIntegerHex(std::wstring Section, std::wstring Ident, int Value)
{
	wchar_t buffer[64];
	wsprintf(buffer, L"%x", Value);
	return WriteString(Section.c_str(),Ident.c_str(),buffer);
}

bool GPIniFile::WriteIntegerHex(std::wstring Section, std::wstring Ident, int len, int Value)
{
	wchar_t buffer[64];
	wchar_t fmt[64];
	wsprintf(fmt, L"%%0%dx", len);
	wsprintf(buffer, (const wchar_t*)fmt, Value);
	return WriteString(Section.c_str(),Ident.c_str(),buffer);
}

bool GPIniFile::WriteBool(std::wstring Section, std::wstring Ident, bool Value)
{
	std::wstring strValue = L"True";
	if(!Value)
		strValue = L"False";

	return WriteString(Section.c_str(),Ident.c_str(),strValue);
}

bool GPIniFile::ReadBool(std::wstring Section, std::wstring Ident, bool Default)
{
	std::wstring strValue = LowerCase(ReadString(Section,Ident,L""));
	if (strValue.size() <= 0)
	{
		return Default;
	}
	else
	{
		if(strValue.compare(L"true") == 0)
			return true;
		else if(strValue.compare(L"false") == 0)
			return false;
		else
			return Default;
	}
}

bool GPIniFile::WriteFloat(std::wstring Section, std::wstring Ident, double Value)
{
	wchar_t buffer[64];
	wsprintf(buffer, L"%lf", Value);
	return WriteString(Section.c_str(),Ident.c_str(),buffer);
}

double GPIniFile::ReadFloat(std::wstring Section, std::wstring Ident, double Default)
{
	std::wstring strFloat = ReadString(Section,Ident,L"");
	if (strFloat.size() <= 0)
	{
		return Default;
	}
	else
	{
		return _wtof(strFloat.c_str());
	}
}

void GPIniFile::ReadSection(std::wstring Section, inistringlist &Strings)
{
	Strings.clear();//
	int nSize = 0, nLen = nSize-2;
	wchar_t *lpszReturnBuffer = 0;
	while(nLen==nSize-2)
	{
		nSize+=MAX_INIFILE_BUFFER_SIZE;
		if(lpszReturnBuffer) delete lpszReturnBuffer;
		lpszReturnBuffer = new wchar_t[nSize];
		nLen = GetPrivateProfileStringW(Section.c_str(),
			NULL,
			NULL,
			lpszReturnBuffer,//
			nSize,
			m_strFileName.c_str());	//
	}
	TCHAR *pName = new wchar_t[MAX_PATH];
	TCHAR *pStart, *pEnd;
	pStart = lpszReturnBuffer;
	pEnd =0;
	while(pStart!=pEnd)
	{
		pEnd = wcschr(pStart,0);
		nLen = pEnd-pStart;
		if(nLen==0) break;
		wcsncpy_s(pName,MAX_PATH,pStart,nLen);
		pName[nLen] = 0;
		std::wstring value = pName;
		Strings.push_back(value);
		pStart = pEnd+1;
	}	
	delete lpszReturnBuffer;
	delete pName;
}

void GPIniFile::ReadSections(inistringlist &Strings)
{
	Strings.clear();//
	int nSize = 0, nLen = nSize-2;
	TCHAR *lpszReturnBuffer = 0;
	while(nLen==nSize-2)
	{
		nSize+=MAX_INIFILE_BUFFER_SIZE;
		if(lpszReturnBuffer) delete lpszReturnBuffer;
		lpszReturnBuffer = new TCHAR[nSize];
		nLen = GetPrivateProfileSectionNamesW(lpszReturnBuffer,nSize,//
			m_strFileName.c_str());	//
	}
	TCHAR *pName = new TCHAR[MAX_PATH];
	TCHAR *pStart, *pEnd;
	pStart = lpszReturnBuffer;
	pEnd =0;
	while(pStart!=pEnd)
	{
		pEnd = wcschr(pStart,0);
		nLen = pEnd-pStart;
		if(nLen==0) break;
		wcsncpy_s(pName,MAX_PATH,pStart,nLen);
		pName[nLen] = 0;
		std::wstring value = pName;
		Strings.push_back(value);
		pStart = pEnd+1;
	}
	delete lpszReturnBuffer;
	delete pName;
}

bool GPIniFile::EraseSection(std::wstring Section)
{
	if(WritePrivateProfileString(Section.c_str(),NULL,NULL,m_strFileName.c_str())==0)
		return false;
	else
		return true;
}

void GPIniFile::ReadSectionValues(std::wstring Section, inistringlist &Strings)
{
	inistringlist   keylist;
	ReadSection(Section, keylist);
	Strings.clear();
	for(inistringlist::iterator  i = keylist.begin(); i!= keylist.end(); i++)
	{
		TCHAR *key;
		key = new TCHAR[MAX_INIFILE_BUFFER_SIZE];
		wcscat_s(key, MAX_INIFILE_BUFFER_SIZE, L"=");
		wcscat_s(key, MAX_INIFILE_BUFFER_SIZE, ReadString(Section, *i, L"").c_str());
		std::wstring value = key;
		Strings.push_back(value);
		delete key;
	}
}

std::wstring GPIniFile::LowerCase(std::wstring value)
{
	std::wstring ret = value;
	for(std::wstring::iterator i = ret.begin(); i< ret.end(); i++)
	{
		if(((*i) >= 'A') && ((*i)<='Z'))
			*i -= 'A'-'a';
	}
	return ret;
}

std::wstring GPIniFile::UpperCase(std::wstring value)
{
	std::wstring ret = value;
	for(std::wstring::iterator i = ret.begin(); i< ret.end(); i++)
	{
		if(((*i) >= 'a') && ((*i)<='z'))
			*i += 'A'-'a';
	}
	return ret;
}